/*******************************************************************************
 * Copyright (c) 2014 Francesco Gabbrielli.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Francesco Gabbrielli - initial API and implementation
 ******************************************************************************/
package it.francescogabbrielli.android.solidalapp.file;

import java.util.LinkedList;
import java.util.List;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.telephony.TelephonyManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.ActionBar.TabListener;
import com.actionbarsherlock.view.Menu;

import it.francescogabbrielli.android.solidalapp.BaseActivity;
import it.francescogabbrielli.android.solidalapp.IntentAction;
import it.francescogabbrielli.android.solidalapp.R;
import it.francescogabbrielli.android.solidalapp.SolidalApp.DataKey;
import it.francescogabbrielli.android.solidalapp.requestendpoint.model.Request;
import it.francescogabbrielli.android.solidalapp.responseendpoint.model.Response;

public abstract class FileActivity<D> extends BaseActivity
			implements TabListener, OnPageChangeListener, FileFragmentListener,
			LoaderCallbacks<D> {
		
	private ViewPager pager;
	private boolean inited;
	
	protected abstract String getProfileFragmentName();
	
	public abstract long getBaseId();
	
	public abstract DataKey getChatKey();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.baseactivity_file);
		
		if (!inited) {
			
	        pager = (ViewPager) findViewById(R.id.file_pager);
	        
	        if (pager!=null) {
	        	
		        pager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
		        	
		        	@Override
		        	public CharSequence getPageTitle(int position) {
		        		switch (position) {
		        		case 0:
		        			return getString(R.string.file_tab_details);
		        		case 1:
		        			return getString(R.string.file_tab_chat);
		        		}
		        		return "";
		        	}
		        	
					@Override
					public int getCount() {
						return 2;
					}
					
					@Override
					public Fragment getItem(int pos) {
						switch (pos) {
						case 0:
							return SherlockFragment.instantiate(FileActivity.this, getProfileFragmentName()); 
						case 1:
							return new ChatFragment();
						}
						return null;
					}
					
				});
		        
		        pager.setOnPageChangeListener(this);
		                				
				ActionBar actionBar = getSupportActionBar();
		    	actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
		    	actionBar.addTab(
			    	actionBar.newTab()
			    		.setTag("details")
			    		.setText(R.string.file_tab_details)
			    		.setTabListener(this));
		    	actionBar.addTab(
			    	actionBar.newTab()
						.setTag("chat")
						.setText(R.string.file_tab_chat)
						.setTabListener(this));
		    	
	        } else {
	        	
	        	FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
	        	ft.add(R.id.file_details_container, SherlockFragment.instantiate(this, getProfileFragmentName()), "details");
	        	ft.add(R.id.file_chat_container, new ChatFragment(), "chat");
	        	ft.commit();
	        	
	        }
	        
	        inited = true;
	        
		}
	
		// if from notifiction...		
		switch(IntentAction.valueOf(getIntent())) {
		case GCM_REQUEST_CHAT_RECEIVED:
		case GCM_RESPONSE_CHAT_RECEIVED:
			forwardNotification();
			break;
		default:
		}
		
	}
		
	@Override
	protected void onResumeFragments() {
		
		super.onResumeFragments();
		
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getSupportMenuInflater().inflate(R.menu.file, menu);
		return true;
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		hideKeyboard();
	}

	@Override
	public void onTabSelected(Tab tab, FragmentTransaction ft) {
		pager.setCurrentItem(tab.getPosition());
	}

	@Override
	public void onTabUnselected(Tab tab, FragmentTransaction ft) {
		
	}

	@Override
	public void onTabReselected(Tab tab, FragmentTransaction ft) {
		
	}

	@Override
	public void onPageScrollStateChanged(int arg0) {
		
	}

	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {
		
	}

	@Override
	public void onPageSelected(int position) {
		getSupportActionBar().setSelectedNavigationItem(position);
	}
	
	public void onClickPhone(View view) {
		TelephonyManager manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		if (manager.getSimState()==TelephonyManager.SIM_STATE_READY) {
			TextView t = (TextView) view;//.findViewById(R.id.profile_phone_text);
			Intent msg = new Intent(Intent.ACTION_VIEW);
			msg.setData(Uri.parse("tel:" + t.getText()));
			startActivity(Intent.createChooser(msg, "Contatta l'utente"));
		}
	}
	
	private interface ChatFragmentExec {
		void exec(ChatFragment f, boolean external);
	}
	
	private List<ChatFragmentExec> execQueue;
	
	private synchronized void execOnChatFragment(ChatFragmentExec exec) {
		ChatFragment f = getChatFragment();
		if (f!=null) {
			exec.exec(f, false);
	    } else {
			if (execQueue==null)
				execQueue = new LinkedList<ChatFragmentExec>();
			execQueue.add(exec);
		}
	}
	
	synchronized void execChatQueue(ChatFragment f) {
		if (execQueue!=null)
			for (ChatFragmentExec exec : execQueue)
				exec.exec(f, true);
		execQueue = null;
	}
	
	private ChatFragment getChatFragment() {
		List<Fragment> fs = getSupportFragmentManager().getFragments();
		if (fs!=null)
			for (Fragment f : fs)
				if (f instanceof ChatFragment)
					return (ChatFragment) f;
		return null;
	}
	
	@Override
	protected void onNewIntent(final Intent intent) {
		
		super.onNewIntent(intent);
		
		execOnChatFragment(new ChatFragmentExec() {
			@Override
			public void exec(ChatFragment cf, boolean external) {
				if (pager!=null)
					getSupportActionBar().setSelectedNavigationItem(1);
				switch(IntentAction.valueOf(intent)) {
				case GCM_REQUEST_CHAT_SENT:
				case GCM_RESPONSE_CHAT_SENT:
					cf.onMessageSent(intent.getLongExtra("id", 0), intent.getStringExtra("error"));
					break;
				case GCM_REQUEST_CHAT_RECEIVED:
				case GCM_RESPONSE_CHAT_RECEIVED:
					cf.onMessageReceived(intent.getStringExtra("message"), external);
					break;
				default:
				}
			}
		});
	}
		
	/** 
	 * Reload data
	 *  
	 * @param restart
	 * 					whether to restart the loader
	 * @param id
	 * 					the id of the bean to load
	 * @param loaderId
	 * 					the loader
	 */
	protected void reload(boolean restart, long id, int loaderId) {
		LoaderManager lm = getSupportLoaderManager();
		if (id>0) {
			Bundle filters = new Bundle();
			filters.putLong("id", id);
			if (restart)
				lm.restartLoader(loaderId, filters, this);
			else
				lm.initLoader(loaderId, filters, this);
		} else {
			Loader<Response> loader = lm.getLoader(loaderId);
			if (loader!=null)
				loader.reset();
		}
	}
	
}
